#include "UapGenerator.h"
#include "UapStateMap.h"
#include "MediaLibrary.h"
#include "ClientUapProxy.h"

namespace tsc
{
namespace sgw
{

using namespace tsc::common;
using UserApplicationPart::ClientCapabilities;

std::map<uint32_t, UapGenerator*> UapGenerator::msGeneratorMap;

/*******************************************************************************
 *
 * Constructor
 *
 ******************************************************************************/
UapGenerator::UapGenerator(
		common::GeneratorEnvironment& ge,
		UserContext* context,
		uint32_t connectionId) :
	common::Generator(ge, UapStateMap::instance().initialState()),
	mpContext(context),
	mpCapabilities(0),
	mConnectionId(connectionId),
	mMediaItemId(common::MediaLibrary::INVALID_MEDIA_ITEM_ID),
	mClientMediaPort(0),
	mServerMediaPort(0),
	mpServerMediaAddress(0),
	mpT643(0)
{
    mpT643 = new Timer(
            ClientUapProxy::instance().getRequestHandler(),
            getConnectionId(),
            UAP_TIMER_ID_T643,
            TIMER_TYPE_UAP);

    // generator is stored in a map with connectionId as a key
	msGeneratorMap.insert(
			std::pair<uint32_t, UapGenerator*>(connectionId, this));

	mpContext->generatorCreated();
} // UapGenerator::UapGenerator

/*******************************************************************************
 *
 * Destructor
 *
 ******************************************************************************/
UapGenerator::~UapGenerator()
{
	if(mpCapabilities) delete mpCapabilities;
	if(mpServerMediaAddress) delete mpServerMediaAddress;

	msGeneratorMap.erase(this->getConnectionId());
	ClientUapProxy::instance().clearConnIdMapping(this->getConnectionId());

	mpT643->cancel();
	delete mpT643;

	mpContext->generatorRemoved();
}

bool
UapGenerator::findGenerator(uint32_t connectionId, UapGenerator*& generator)
{
	std::map<uint32_t, UapGenerator*>::iterator it = msGeneratorMap.find(connectionId);
	if(it != msGeneratorMap.end())
	{
		generator = it->second;
		return true;
	}
	return false;
}


ClientCapabilities*
UapGenerator::getCapabilities() const
{
	return mpCapabilities;
}

void
UapGenerator::setCapabilities(const ClientCapabilities* capabilities)
{
	mpCapabilities = new ClientCapabilities(*capabilities);
}

UserContext*
UapGenerator::getContext() const
{
	return mpContext;
}

//uint8_t
//UapGenerator::getUserGeneratorId() const
//{
//	return mUserGeneratorId;
//}


uint32_t
UapGenerator::getConnectionId() const
{
	return mConnectionId;
}

uint32_t
UapGenerator::getClientMediaPort() const
{
    return mClientMediaPort;
}

void
UapGenerator::setClientMediaPort(uint32_t clientMediaPort)
{
    mClientMediaPort = clientMediaPort;
}

uint32_t
UapGenerator::getMediaItemId() const
{
    return mMediaItemId;
}

void
UapGenerator::setMediaItemId(uint32_t mediaItemId)
{
    mMediaItemId = mediaItemId;
}

uint32_t
UapGenerator::getServerMediaPort() const
{
    return mServerMediaPort;
}

void
UapGenerator::setServerMediaPort(uint32_t mediaServerPort)
{
    mServerMediaPort = mediaServerPort;
}

ProtocolsCommon::IpAddress*
UapGenerator::getServerMediaAddress() const
{
    return mpServerMediaAddress;
}

void
UapGenerator::setServerMediaAddress(ProtocolsCommon::IpAddress* ip)
{
    if(mpServerMediaAddress)
    {
        delete mpServerMediaAddress;
    }
    mpServerMediaAddress = new ProtocolsCommon::IpAddress(*ip);
}

void
UapGenerator::startT643(unsigned long valueMs)
{
    mpT643->start(valueMs);
}

void
UapGenerator::cancelT643()
{
    mpT643->cancel();
}

} // namespace sgw
} // namespace tsc
